import random
import re

from info import constants, db
from info import redis_store
from info.models import User
from info.response import RET
from . import passport_blueprint
from flask import request,make_response,jsonify,session
from libs.captcha.captcha import captcha
from info.utils.sms import sendTemplateSMS


#    1,随机生成4位字符串
#    2,调用pillow包中的类,进行图形绘制
#    3,将图片输出到response对象中返回
# 定义生成验证图形码的函数
@passport_blueprint.route('/image_code')
def image_code():
    # 1调用第三方的包,生成图形验证码
    text,code,image = captcha.generate_captcha()
    #2,保存到code得到redis的验证码,进行后续验证
    #获取客户端请求的唯一标示[数据]
    code_id = request.args.get("code_id")
    #给获取的验证码给一个时间限制
    redis_store.setex(code_id,constants.IMAGE_CODE_REDIS_EXPIRES,code)
    # 返回图片
    response = make_response(image)
    # 设置响应头中,返回数据类型,告诉浏览器如何解析返回的数据
    response.headers["Content-Type"] = 'image/png'
    return response





@passport_blueprint.route('/sms_code',methods = ['POST'])
def sms_code():
    '''短信验证
    1接收,用户输入的验证码,和手机号
    '''
    mobile = request.json.get('mobile')
    image_request = request.json.get('image_code')
    image_code_id = request.json.get('image_code_id')
    #2,从redis中读取验证图形码,吧数据库中的图形验证和用户输入的进行验证
    image_redis =redis_store.get(image_code_id)
    if image_redis is None:
        return jsonify(errno = RET.NODATA,errmsg = '图形验证码过期')
    #3,验证输入如的验证图形码是否正确
    if image_request != image_redis.decode():
        return jsonify(errno = RET.DATAERR,errmsg = '输入的验证码不正确')
    #4,验证手机号格式
    if not re.match(r'^1[3-9]\d{9}$', mobile):
        return jsonify(errno = RET.NODATA,errmsg = '手机号格式错误')
    #5,判断手机号是否存在
    mobile_count = User.query.filter_by(mobile = mobile).count()
    if mobile_count > 0 :
        return jsonify(errno = RET.DATAEXIST,errmsg = '手机号以存在')

    #验证成功执行的代码.随机生成一个 6位数数字
    smscode = str(random.randint(100000,999999))
    #设置,发送短信列表中的参数[验证随机字符串smscode ,设置有效期]
    sendTemplateSMS(mobile,[smscode,'5'],1)
    #保存验证码到redis
    print(smscode)
    redis_store.setex(mobile,constants.SMS_CODE_REDIS_EXPIRES, smscode)

    return jsonify(errno = RET.OK,errmsg = "")





@passport_blueprint.route('/register',methods = ["POST"])
def register():
    """注册:
    添加,用户输入的数据,给添加的数据指定给个对象并赋值字段
    手机号,验证码,密码
    """
    mobile = request.json.get('mobile')
    smscode = request.json.get('smscode')
    password = request.json.get('password')
    #2,验证接收的数据,验证所有非空数据
    if not all ([mobile,smscode,password]):
        return jsonify(errno = RET.NODATA,errmsg = "数据不完整")
    # 读取验证码进行判断
    smscode_redis = redis_store.get(mobile)
    if smscode_redis is None:
        return jsonify(errno = RET.NODATA,errmsg = '短信验证码过期')
    #验证手机验证码和redis存的验证码是否一致
    if smscode != smscode_redis.decode():
        return jsonify(errno = RET.DATAERR,errmsg = '短信验证码错误')

    #验证成功处理逻辑,创建新用户,并赋值,字段.保存
    user = User()
    user.mobile = mobile
    user.nick_name = mobile
    user.password = password
    db.session.add(user)
    db.session.commit()

# 响应返回
    return jsonify(errno = RET.OK,errmsg = "")





@passport_blueprint.route('/login',methods = ['POST'])
def login():
    #1,接收用户输入的手机号,和密码
    mobile = request.json.get('mobile')
    password = request.json.get("password")
    # 验证：直接进行查询，如果未查到，说明参数错误
    if not all ([mobile,password]):
        return jsonify(errno = RET.NODATA,errmsg = '参数不完整')

    #验证成功后处理的代码
    #处理,查询用户
    user = User.query.filter_by(mobile = mobile).first()
    if user is None:
        return jsonify(errno = RET.DATAERR,errmsg = '手机号错误')
    # 验证密码,将密码加密,队两个密码进行验证
    if user.check_password(password):
        # 密码正确,登陆成功要执行的逻辑
        # 需要给账户设置状态保持,方便再其他阿德试图中判断登陆
        session['user_id'] = user.id
        session['nick_name'] = user.nick_name
        return jsonify(errno =RET.OK,errmsg = "")
    else:
        jsonify(errno = RET.DATAERR,errmsg = '密码错误')
        # 响应



@passport_blueprint.route('/logout',methods = ['POST'])
def logout():
    """退出删除保持状态信息"""

    #从字典中删除键
    session.pop('user_id')
    session.pop('nick_name')
    return jsonify(errno = RET.OK,errmsg = "")